program ppServer;
{----------------------------------------------
  pp sserver daemon
  

-----------------------------------------------}

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Libc,
  chatServer in 'chatServer.pas',
  md5 in 'md5.pas',
  global in 'global.pas',
  wndes in 'wndes.pas',
  chatTypes in 'chatTypes.pas';

Var
  // vars for daemonizing 
  bHup    ,
  bTerm   : boolean;
  fLog    : Text;
  logname : string;
  aOld    ,
  aTerm   ,
  aHup    : PSigAction;   //was pSigActionRec
  ps1     : psigset;
  sSet    : cardinal;
  pid     : longint;
  secs    : longint;

// handle SIGHUP & SIGTERM 
procedure DoSig(sig : longint);cdecl;
begin
  case sig of
    SIGHUP  : bHup  := true;
    SIGTERM : bTerm := true;
  end;
end;

// open the log file 
Procedure NewLog;
Begin
  Assignfile(fLog,logname);
  Rewrite(fLog);
  Writeln(flog,'Server started at '+ formatdatetime('yyyy/mm/dd',now));
  Closefile(fLog);
End;

begin
  // TODO -oUser -cConsole Main : Insert code here 
  logname := GetCurrentDir +'/logs/' + formatdatetime('yyyymmdd',now) + '.log';
  secs := 10;

  // set global daemon booleans 
  bHup := true; // to open log file 
  bTerm := false;

  // block all signals except -HUP & -TERM
  sSet := $ffffbffe;
  ps1 := @sSet;
  sigprocmask(sig_block,ps1,nil);

  // setup the signal handlers
  new(aOld);
  new(aHup);
  new(aTerm);
  aTerm^.__sigaction_handler := @DoSig;
  aTerm^.sa_flags := 0;
  aTerm^.sa_restorer := nil;
  aHup^.__sigaction_handler:= @DoSig;
  aHup^.sa_flags := 0;
  aHup^.sa_restorer := nil;
  SigAction(SIGTERM,aTerm,aOld);
  SigAction(SIGHUP,aHup,aOld);

  // daemonize
  pid := Fork;
  Case pid of
    0 : Begin // we are in the child
           Close(input);  // close standard in
           AssignFile(output,'/dev/null');
           ReWrite(output);
           AssignFile(ErrOutPut,'/dev/null');
           ReWrite(ErrOutPut);
         End;
    -1: secs := 0;     // forking error, so run as non-daemon
    Else Halt;          // successful fork, so parent dies
  End;  //case
  
  //Create any objects before you go into the processing loop
  echatServer := TChatServer.Create;
  
  // begin processing loop
  Repeat
    If bTerm Then
    begin
      echatServer.Free;
      BREAK;
    end Else
      __sleep(secs*1000);
  Until bTerm;
end.
